package view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
import java.io.IOException;
import java.util.StringTokenizer;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;

/**
 * Class is responsible for help frame.
 * Frame contains: 	menu buttons enable to choose specific help informaion.
 * 					Help Data text field show the help information.
 * 					Save to file button enable choosing file to save 
 * 					the help data into.
 */
public class HelpFrame extends JFrame
{
	/**
	 * Serial version ID - for serialization
	 */
	private static final long serialVersionUID = -5198547881188242684L;
	public static HelpFrame currentHelpFrame = null;
	
	private		JSplitPane	splitPaneV;
	private		JSplitPane	splitPaneH;
	private		JPanel		panelTopics;
	private		JPanel   	panelDesc;
	private		JPanel		panelActions;
	private     JTextArea   txtArea;
	private     JLabel      lableDesc;

	/**
	 * C'tor - 
	 * Define the frame.
	 */
	public HelpFrame()
	{
		/* Set the frame title */ 
		setTitle( "FW Help" );
		
		JPanel topPanel = new JPanel();
		topPanel.setLayout( new BorderLayout() );
		getContentPane().add( topPanel );

		/* Create the panels */
		createPanelTopics();
		createPanelDesc();
		createPanelActions();

		/* Create the vertical splitter pane */
		splitPaneV = new JSplitPane( JSplitPane.VERTICAL_SPLIT );
		topPanel.add( splitPaneV, BorderLayout.CENTER );

		/* Create the horizantal splitter pane */
		splitPaneH = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT );
		splitPaneH.setLeftComponent( panelTopics);
		splitPaneH.setRightComponent(panelDesc);

		splitPaneV.setLeftComponent( splitPaneH );
		splitPaneV.setRightComponent( panelActions );
		
		pack();
		setLocationRelativeTo(null);
		setVisible(false);
		
		currentHelpFrame = this;
	}

	/**
	 * returns current frame if exists, ales creates it.
	 * @param N\A
	 * @return help frame
	 */
	public static HelpFrame getInctance()
	{
		if(currentHelpFrame == null)
		{
			currentHelpFrame = new HelpFrame();
		}
		
		return currentHelpFrame;
	}
	
	/**
	 * Create the panel topics help (the left panel)
	 * @param  N\A
	 * @return N\A
	 */
	public void createPanelTopics()
	{
		panelTopics = new JPanel();
		
		/* Create all the buttons to put in the panel */
		JButton mainWinButton   = new JButton(Globals.MAIN);
		JButton loginWinButton  = new JButton(Globals.LOGIN);
		JButton errorWinButton  = new JButton(Globals.ERROR);
		JButton loggerWinButton  = new JButton(Globals.LOGGER);
		JButton lregExpWinButton  = new JButton(Globals.REG_EXP);
		JButton ruleExpWinButton  = new JButton(Globals.RULES);
		JButton aboutWinButton  = new JButton(Globals.ABOUT);

		/* put all the buttons on the panel */ 
		panelTopics.setLayout(new BoxLayout(panelTopics, BoxLayout.Y_AXIS));
		panelTopics.add(loginWinButton);
		panelTopics.add(mainWinButton);
		panelTopics.add(lregExpWinButton);
		panelTopics.add(ruleExpWinButton);
		panelTopics.add(loggerWinButton);
		panelTopics.add(errorWinButton);
		panelTopics.add(aboutWinButton);

		/* create action listener for main button - 
		 * click on this button will show the help for the main frame*/
		mainWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				ShowDesc(Globals.MAIN);
			}
		}
		);
		
		/* create action listener for login button - 
		 * click on this button will show the help for the login frame */
		loginWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae)
		    {
				ShowDesc(Globals.LOGIN);
			}
		}
		);
		
		/* create action listener for error button - 
		 * click on this button will show the help for the error frame */
		errorWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				ShowDesc(Globals.ERROR);
			}
		}
		);
		
		/* create action listener for logger button - 
		 * click on this button will show the help for the logger frame */
		loggerWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				ShowDesc(Globals.LOGGER);
			}
		}
		);

		/* create action listener for regular expression button - 
		 * click on this button will show the help for the regular expression */
		lregExpWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				ShowDesc(Globals.REG_EXP);
			}
		}
		);

		/* create action listener for rules expression button - 
		 * click on this button will show the help for the rules expression */
		ruleExpWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				ShowDesc(Globals.RULES);
			}
		}
		);
		
		/* create action listener for regular about button - 
		 * click on this button will show the about data */
		aboutWinButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				ShowDesc(Globals.ABOUT);
			}
		}
		);
	}
	
	/**
	 * Create the panel of the Description (the right panel)
	 * this panle show the help data for the topic that choosen
	 * @param  N\A
	 * @return N\A
	 */
	public void createPanelDesc()
	{
		panelDesc = new JPanel();
		txtArea = new JTextArea();
		txtArea.setEditable(false);

		/* initial title*/
		lableDesc = new JLabel("Please Choose A Help topic");

		/* set the field's properties*/
		panelDesc.setLayout( new BorderLayout() );
        panelDesc.setPreferredSize( new Dimension(800, 500) );
        panelDesc.setMinimumSize( new Dimension( 100, 50 ) );
		panelDesc.add(lableDesc, BorderLayout.NORTH);
		panelDesc.add(txtArea, BorderLayout.CENTER);
		

	}
	
	/**
	 * Create the panel of the operations (the lower panel)
	 * @param  N\A
	 * @return N\A
	 */
	public void createPanelActions()
	{
		/*Creaet the panel's buttons */
		JButton prevButton = new JButton( "Prev" );
		JButton nextButton = new JButton( "Next" );
		JButton saveButton = new JButton( "Save To File" );

		/* disable the turning pages buttons  - it for later versions */
		prevButton.setEnabled(false);
		nextButton.setEnabled(false);
		
		panelActions = new JPanel();
		panelActions.setLayout(new BoxLayout(panelActions, BoxLayout.X_AXIS));
		panelActions.add(prevButton);
		panelActions.add(nextButton);
		panelActions.add(saveButton);
		
		/* create action listener for save to file button - 
		 * click on this button will enable to save the current help page into file */
		saveButton.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent ae) 
		    {
				SaveToFile();
			}
		}
		);		
	}

	/**
	 * Load the help data of the topic that choosen
	 * @param  String btnName - the name of the button that clicked
	 * @return N\A
	 */
	public void ShowDesc(String btnName) 
	{
		txtArea.setText("\r\n");
		
		if(btnName.equals(Globals.MAIN))
		{
			/* Main button choosen - load it data */
			lableDesc.setText("Main Window description");
			if(Settings.userMode.equals(UserMode.STANDART))
			{
				txtArea.append("\r\n  Regular expression - window where you can see regular expression for for the current FW. \r\n");
				txtArea.append("\r\n  Rules - window where you can see rules for the current FW. \r\n");
			}
			else if(Settings.userMode.equals(UserMode.ADVANCED))
			{
				txtArea.append("\r\n  Regular expression - window where new regular expression for some protocol can be added. \r\n");
				txtArea.append("\r\n  Rules - window where you can see rules for the current FW," +
							" add / delete / edit rule," +
							" load / save some ruleset \r\n");				
			}
			txtArea.append("\r\n  Logger -  window where you can see logger reports and statistics. \r\n");
			txtArea.append("\r\n  Exception List - window where you can see error reports. \r\n");
			txtArea.append("\r\n  Help - window where you can see system general help. \r\n");
			txtArea.append("\r\n  Fw on/off - button that turn on/off the FW. \r\n");
		}
		else if(btnName.equals(Globals.LOGIN))
		{
			/* login button choosen - load it data */
			
			lableDesc.setText("Login Window description");
			txtArea.append("\r\n  This Login window make a login to the FW System Manager. \r\n");
			txtArea.append("\r\n  Please follow the instruction: \r\n");
			txtArea.append("\r\n  If you are not an authorize user or forgot your password\r\n");
			txtArea.append("\r\n  please talk to the administrator to add you to the authorize list. \r\n");
			txtArea.append("\r\n  If you are an authorize user: \r\n");
			txtArea.append("\r\n	1. Enter your user name in the user name field \r\n");
			txtArea.append("\r\n	2. Enter your password in the password field \r\n");
			txtArea.append("\r\n	3. Enter the server ip in the server ip field \r\n");
			txtArea.append("\r\n	4. Press the login button - the FW application will be open\r\n");
		}
		else if(btnName.equals(Globals.ERROR))
		{
			/* Errors button choosen - load it data */
			
			lableDesc.setText("Error Window description");
			txtArea.append("\r\n  This Exceptions window show all the exceptions occured in the FW aplication. \r\n");
			txtArea.append("\r\n  - You can press on the clear button - to clean all the exceptions from the log. \r\n");
			txtArea.append("\r\n  - You can press on the save to file button, for saving all the exceptions to file, \r\n");
			txtArea.append("\r\n     this button will open a file chooser to choose / create afile to save exceptions to. \r\n");
			txtArea.append("\r\n  - Pressing on the save to file button enable choosing file for saving to. \r\n");
		}
		else if(btnName.equals(Globals.LOGGER))
		{
			/* Logger button choosen - load it data */
			
			lableDesc.setText("Logger Window description");
			txtArea.append("\r\n  This Logger window displays reports of the FW System Manager. \r\n");
			txtArea.append("\r\n  Button Dynamic Mode - turn on iteractive mode of the reports. \r\n");
			txtArea.append("\r\n  Button Static Mode - turn on static mode of the reports. \r\n");
			txtArea.append("\r\n  Button filter display filter options:\r\n" +
					"\r\n	1. days number - the logger data will be displayed for the defined days number. \r\n" +
					"\r\n	2. protocol - the logger data where defined protocol is mentioned will be displayed.\r\n" +
					"\r\n	3. IP - the logger data where defined IP, port, direction are mentioned will be displayed. \r\n");
			txtArea.append("\r\n  Button reset - returns log options to default - without filtering, for the last day. \r\n");
			txtArea.append("\r\n  Button Logger on/off - turns logger on/off appropriatly. \r\n");			
		}
		else if(btnName.equals(Globals.REG_EXP))
		{
			/* Regular expression button choosen - load it data */
			if(Settings.userMode.equals(UserMode.ADVANCED))
			{
				lableDesc.setText("Regular Expression description");
				txtArea.append("\r\n  Table in this window display all defined protocols for the FW. \r\n");				
				txtArea.append("\r\n  The table contain: protocol name, in regular expression, out regular expression. \r\n");				
				txtArea.append("\r\n  Button Add protocol    - allows to add new protocol to the FW DB \r\n");				
				txtArea.append("\r\n  Button Edit protocol   - allows to edit selected protocol and save changes into the FW DB\r\n");				
				txtArea.append("\r\n  Button Delete protocol - allows to delete selected protocol from the FW DB\r\n");				
				txtArea.append("\r\n  ---------------------------------------------------------------------------\r\n");
				txtArea.append("\r\n In order to Add \\ Edit protocol");				
				txtArea.append("\r\n  1. Press Add button for add or choose protocol from the protocol's table for edit.");				
				txtArea.append("\r\n  2. Fill Protocol name and In/Out regular expresions (name only in add action)");				
				txtArea.append("\r\n  3. Press Finish Button\r\n");				
				txtArea.append("\r\n     Protocol name is unique");				
				txtArea.append("\r\n     Regular Exprsion is  Unix style regexp\r\n");				
				txtArea.append("\r\n  ---------------------------------------------------------------------------\r\n");
				txtArea.append("\r\n In order to detete a protocol");				
				txtArea.append("\r\n  1. Select protocol from the protocol's table.");				
				txtArea.append("\r\n  2. Press delete button\r\n");				
			}
			else
			{
				lableDesc.setText("Regular Expression description");
				txtArea.append("\r\n  Table in this window display all defined protocols for the FW. \r\n");				
				txtArea.append("\r\n  The table contain: - protocol name\r\n");				
				txtArea.append("\r\n                                   - in regular expression\r\n");				
				txtArea.append("\r\n                                   - out regular expression\r\n");				 
				txtArea.append("\r\n  Theis windows also contain standard button: help, finish, cancel. \r\n");				
				
			}
		}
		else if(btnName.equals(Globals.RULES))
		{
			/* Rules button choosen - load it data, 
			 * distinction between advanced user  to standart user */
			
			if(Settings.userMode.equals(UserMode.ADVANCED))
			{
				/* Load help data for Rules-Advance user */
				
				lableDesc.setText("Advanced Rules Window description");
				txtArea.append("\r\n  Two tables in this window displays In and Out rules of a ruleset  in the FW, \r\n");				
				txtArea.append("\r\n  it show by default the active ruleset (you can see other rulset, follow the instroctions). The current rule set name present on the buttom bar \r\n");				
				txtArea.append("\r\n  ----------------------------------------------------------------------------------------------------------------------------------------------\r\n");				
				txtArea.append("\r\n  - Button New rule set - allows to create a new rule set. enter ruleset name and press finish . \r\n");				
				txtArea.append("\r\n  - Button Load rule set - choose existing rule set from the list and press finish - it load the choosen rule set. \r\n");				
				txtArea.append("\r\n  - Button Delete rule set - choose a rule set from the list and press finish. it delete the rule set choosen. \r\n");				
				txtArea.append("\r\n     you can't delete the active rule set or the the presented ruleset. \r\n");				
				txtArea.append("\r\n  - Button Active rule set - it load the active rule set to present on the rules tables. \r\n");				
				txtArea.append("\r\n  - Button Set as active - save the ruleset from tables as active FW ruleset. \r\n");				
				txtArea.append("\r\n  - Button Add Rule - allows to add rule to the ruleset in the tables.");				
				txtArea.append("\r\n    you can add ruleset by context (by protocol) or by IP.");				
				txtArea.append("\r\n    add by ip - you can choose between in / out /both.");				
				txtArea.append("\r\n    add by content - the action can be only deny, it deny all protocol except the choosen protocol in the selection port \r\n");				
				txtArea.append("\r\n  - Button Delete Rule - select rule on the table and press delete. it delete the selected rule \r\n");				
				txtArea.append("\r\n  - Button Edit Rule - allows to edit selected in the table rule in the ruleset. the instructions on that window same as add rule.\r\n");				
				txtArea.append("\r\n  * after the window title shows that the ruleset in the tables isn't the current FW ruleset. \r\n");				

			}
			else if(Settings.userMode.equals(UserMode.STANDART))
			{
				/* Load help data for Rules - standart user */

				lableDesc.setText("Standart Rules Window description");
				txtArea.append("\r\n  Two tables in this window displays In and Out rules of a ruleset  in the FW, \r\n");				
				txtArea.append("\r\n  it show by default the active ruleset (you can see other rulset, follow the instroctions). The current rule set name present on the buttom bar \r\n");				
				txtArea.append("\r\n  ----------------------------------------------------------------------------------------------------------------------------------------------\r\n");				
				txtArea.append("\r\n  - Button Load rule set - choose existing rule set from the list and press finish - it load the choosen rule set. \r\n");				
				txtArea.append("\r\n  - Button Active rule set - it load the active rule set to present on the rules tables. \r\n");				
				txtArea.append("\r\n  - Button Set as active - save the ruleset from tables as active FW ruleset. \r\n");				
				txtArea.append("\r\n  * after the window title shows that the ruleset in the tables isn't the current FW ruleset. \r\n");				
			}
		}
		else if(btnName.equals(Globals.ABOUT))
		{
			/* about button choosen - load it data */

			lableDesc.setText("About");
			txtArea.append("\r\n  FireWall Projects ver 1.3.0 \r\n");				
			txtArea.append("\r\n  ------------------------------------ \r\n");
			txtArea.append("\r\n  Operating System: Linux \r\n");				
			txtArea.append("\r\n  Copyright @ 2006-2007 \r\n");				
			txtArea.append("\r\n  Developed by:   \r\n");
			txtArea.append("\r\n  Leon    Vaidman - Coach - sleonv@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Tom     Zikel - Integrator - stzickel@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Nir     Gigi  - Documenter - sgigi@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Maya    Caspi - Code Review - smayaca@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Evgeny  Sholman - Designer - shulzhen@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Evgenya Alperin - Tracer - salperin@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Evgenya Feldman - On Site customer - sevgf@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Yaron   Wittenstein - Acceptance Tests - syaronw@t2.technion.ac.il \r\n");				
			txtArea.append("\r\n  Yair    Kuspat - Tester - syairku@t2.technion.ac.il \r\n");				
		}

		// update the UI - load changes
		panelDesc.updateUI();
		setVisible(true);
	}
	
	/**
	 * Enable saving the help description into file 
	 * @param  N\A
	 * @return N\A
	 */
	private void SaveToFile() 
	{
		JFileChooser chooser = new JFileChooser();
		
		try
		{
			/* Show chooser file window to the user for choosing file to save into */
			if(chooser.showSaveDialog(this) ==JFileChooser.APPROVE_OPTION)
			{
				String strFilePath = chooser.getSelectedFile().getPath();
				FileWriter fileOutput = new FileWriter(strFilePath);

				String allText = txtArea.getText() ;
				StringTokenizer st = new StringTokenizer(allText,"\n") ;

				/* Write th topic tittle into the file */ 
				fileOutput.write(lableDesc.getText() + "\r\n");
				fileOutput.write("-----------------------------------------\r\n");
				
				/* copy all help description of the current topic into the file */
				while (st.hasMoreTokens()) 
					fileOutput.write(st.nextToken() + "\r\n");
				
				fileOutput.close();
			}
		}
		catch (IOException ex) 
		{
			JOptionPane.showMessageDialog(this, "The action can not be done\n" +
						ex.getMessage());
		}
	}
}
